package com.ap.core.bulkupload.info.builder;

import java.io.InputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ap.core.bulkupload.info.BulkUploadBaseInfo;
import com.ap.core.bulkupload.info.BulkUploadMerchantResponseInfo;
import com.ap.core.bulkupload.info.impl.BulkUploadMerchantResponseInfoImpl;
import com.ap.core.bulkupload.jaxb.domain.DistributorIdType;
import com.ap.core.bulkupload.jaxb.domain.FileHdrType;
import com.ap.core.bulkupload.jaxb.domain.Merchant;
import com.ap.core.bulkupload.jaxb.domain.Trailer;
import com.ap.core.bulkupload.listener.ParserListener;
import com.ap.core.bulkupload.provider.MerchantRegistrationServiceProvider;
import com.ap.core.bulkupload.service.XmlParserService;
import com.ap.core.bulkupload.translator.BulkUploadMerchantResponseTranslator;
import com.ap.core.exception.APCoreException;

/**
 * The Class BulkUploadMerchantResponseInfoBuilder.
 */
public class BulkUploadMerchantResponseInfoBuilder implements
		BulkUploadInfoBuilder {

	/** The log. */
	private static final Logger log = LoggerFactory.getLogger(BulkUploadMerchantResponseInfoBuilder.class);
	
	/** The xml parser service. */
	private XmlParserService xmlParserService;
	
	/** The merchant registration service provider. */
	private MerchantRegistrationServiceProvider merchantRegistrationServiceProvider;
	
	/** The bulk upload merchant response translator. */
	private BulkUploadMerchantResponseTranslator bulkUploadMerchantResponseTranslator;
	
	/* (non-Javadoc)
	 * @see com.ap.core.bulkupload.info.builder.BulkUploadInfoBuilder#populateInfo(java.io.File)
	 */
	@Override
	public BulkUploadBaseInfo populateInfo(InputStream inputStream) throws APCoreException {
		
		BulkUploadMerchantResponseInfo merchantResponseInfo = null;
	
		try {
			log.debug("populating BulkUploadMerchantResponseInfo.");
			
			final BulkUploadMerchantResponseInfoBuilderProcessor  merchantResponseInfoBuilderProcessor = 
					new BulkUploadMerchantResponseInfoBuilderProcessor(inputStream);
			merchantResponseInfo = merchantResponseInfoBuilderProcessor.process();			
			log.info("BulkUploadMerchantResponseInfo data ["+merchantResponseInfo.toString()+"]");
			
			return merchantResponseInfo;
			
		}catch(APCoreException e) {
			log.error("Exception ocurrred ["+e.getMessage()+"]");
			throw e;
 		}   catch (Exception e) {
			log.error("Exception ocurrred ["+e.getMessage()+"]");
			throw new APCoreException(e);			
		}
	}

	/**
	 * Sets the xml parser service.
	 *
	 * @param xmlParserService the xmlParserService to set
	 */
	public void setXmlParserService(XmlParserService xmlParserService) {
		this.xmlParserService = xmlParserService;
	}

	
	/**
	 * Sets the merchant registration service provider.
	 *
	 * @param merchantRegistrationServiceProvider the new merchant registration service provider
	 */
	public void setMerchantRegistrationServiceProvider(MerchantRegistrationServiceProvider merchantRegistrationServiceProvider) {
		this.merchantRegistrationServiceProvider = merchantRegistrationServiceProvider;
	}


	/**
	 * Sets the bulk upload merchant response translator.
	 *
	 * @param bulkUploadMerchantResponseTranslator the bulkUploadMerchantResponseTranslator to set
	 */
	public void setBulkUploadMerchantResponseTranslator(
			BulkUploadMerchantResponseTranslator bulkUploadMerchantResponseTranslator) {
		this.bulkUploadMerchantResponseTranslator = bulkUploadMerchantResponseTranslator;
	}
	
	
	/**
	 * The Class BulkUploadMerchantResponseInfoBuilderProcessor.
	 */
	private class BulkUploadMerchantResponseInfoBuilderProcessor implements ParserListener {

		/** The input stream. */
		private final  InputStream inputStream;
		
		/** The distributor id. */
		private String distributorId;
		
		/**
		 * Instantiates a new bulk upload merchant response info builder processor.
		 *
		 * @param inputStream the input stream
		 */
		BulkUploadMerchantResponseInfoBuilderProcessor(InputStream inputStream) {
			this.inputStream = inputStream;
		}
		
		/**
		 * Process.
		 *
		 * @return the bulk upload merchant response info impl
		 * @throws APCoreException the aP core exception
		 */
		BulkUploadMerchantResponseInfoImpl process() throws APCoreException {
			BulkUploadMerchantResponseInfoImpl merchantResponseInfo = new BulkUploadMerchantResponseInfoImpl();
			
			/* Parse xml file */
			xmlParserService.parse(inputStream, this);
			
			/*Build response object */
			merchantResponseInfo.setMerchantRegBulkUploadResponse(bulkUploadMerchantResponseTranslator.buildResponse());
			
			return merchantResponseInfo;
		}
		
		/* (non-Javadoc)
		 * @see com.ap.core.bulkupload.listener.ParserListener#onFileHeader(com.ap.core.bulkupload.jaxb.domain.FileHdrType)
		 */
		@Override
		public void onFileHeader(FileHdrType fileType) {
			bulkUploadMerchantResponseTranslator.setFileHeader(fileType);
		}

		/* (non-Javadoc)
		 * @see com.ap.core.bulkupload.listener.ParserListener#onDistributor(java.lang.String)
		 */
		@Override
		public void onDistributor(DistributorIdType distributorIdType) {
			this.distributorId = distributorIdType.getValue();			
			bulkUploadMerchantResponseTranslator.setDistributor(distributorIdType);
		}

		/* (non-Javadoc)
		 * @see com.ap.core.bulkupload.listener.ParserListener#onMerchant(com.ap.core.bulkupload.jaxb.domain.Merchant)
		 */
		@Override
		public void onMerchant(Merchant merchant) {
			boolean isSuccessful = merchantRegistrationServiceProvider.registerMerchant(distributorId, merchant);
			bulkUploadMerchantResponseTranslator.setMerchant(merchant, isSuccessful);
		}

		/* (non-Javadoc)
		 * @see com.ap.core.bulkupload.listener.ParserListener#onTrailer(com.ap.core.bulkupload.jaxb.domain.Trailer)
		 */
		@Override
		public void onTrailer(Trailer trailer) {
			/* Do nothing, as no need of reading trailer count */
		}
		
	}
}
